import os


from presence import ps
from fvutil.managers import text, audio, objectmanager


# For live audio
from audio import  mixerinterface

# For interfacing with flash
from ui import flashinterface


import ui.uiconstants as uicon
import gobject

from data import db, broker, textmanager, loginmanager, interactionmanager, shoppingmanager
from poll import pollmanager

# For commandline args
import getopt

LAPTOP = False
FLASH_LOCAL = True        # normally True for deployment, False for testing UI from remote machine

class Engine:

    
    def __init__(self, iface="wlan0",configfile=None):

        
        # Initialize audio service
        self._audio = audiomanager.AudioManager(self._am, self._mixer, d)
        # Initialize TextMsgService

        

        
        self._login.connect( 'login_result', self.onLoginResult)
        # Connect to UI events
        self._fi.connect_signal('login', self._login.onLogin)
        
        #self._fi.connect_signal('edit_object', self._broker.onEditObject)
        self._fi.connect_signal('edit_object', self._mixer.onChange)
        self._fi.connect_signal('edit_quality', self._broker.onEditQuality)
        # Asynch audio UI events
        self._fi.connect_signal('start_record' , self._mixer.onStartRecord)
        self._fi.connect_signal('stop_record', self._mixer.onStopRecord)
        self._fi.connect_signal('start_play', self._mixer.onStartPlay)
        self._fi.connect_signal('stop_play', self._mixer.onStopPlay)
        self._fi.connect_signal('poll_start_record', self._mixer.onStartRecord)
        self._fi.connect_signal('poll_start_record', self._poll.onStartRecord)
        self._fi.connect_signal('poll_stop_record', self._mixer.onStopRecord)
        self._fi.connect_signal('poll_stop_record', self._poll.onStopRecord)
        self._fi.connect_signal('poll_start_play', self._mixer.onStartPlay)
        self._fi.connect_signal('poll_start_play', self._poll.onStartPlay)
        self._fi.connect_signal('poll_stop_play', self._mixer.onStopPlay)
        self._fi.connect_signal('poll_stop_play', self._poll.onStopPlay)
        self._fi.connect_signal('send_object', self._broker.onSendObject)
        
        self._fi.connect_signal('get_messages', self._timeline.getMessages)
        self._fi.connect_signal('get_message_count', self._timeline.getMessageCount)
        
        # Connect to presence events
        self._presence.connect( 'online', self._fi.updateObject )
        self._presence.connect( 'online', self._mixer.onAddInput )
        self._presence.connect( 'object_offline', self._fi.updateObject )
        self._presence.connect( 'object_offline', self._mixer.onOffline )
                
        # Asynch audio flash callbacks
        self._mixer.connect('my_ssrc', self._presence.onMySSRC)
        self._mixer.connect('started_record', self._fi.startedRecord)
        self._mixer.connect('stopped_record', self._fi.stoppedRecord)
        self._mixer.connect('started_play', self._fi.startedPlay)
        self._mixer.connect('stopped_play', self._fi.stoppedPlay)
        self._audio.connect('sent_audio', self._fi.sentObject)

        self._audio.connect('received_audio', self._fi.updateObject)
        self._audio.connect('received_audio', self._mixer.onAddInput)

        # Asynch text UI callbacks
        self._text.connect('created_text', self._fi.sentObject)
        self._text.connect('received_text', self._fi.updateObject)

        self._shopping.connect('created_list', self._fi.sentObject)
        self._shopping.connect('received_list', self._fi.updateObject)

       
        # Asynch poll UI callbacks
        self._poll.connect('created_poll', self._fi.sentObject)
        self._poll.connect('received_poll', self._fi.updateObject)
        self._poll.connect('submitted_pollvote', self._fi.sentObject)
        self._poll.connect('received_pollresults', self._fi.resultsReady)
        
        # audio requests from UI
        self._fi.connect_signal('push_to_talk', self._mixer.onMIC)
        self._fi.connect_signal('push_to_talk', self._presence.onChangeStatus)
        self._mixer.connect( 'ack_push_to_talk', self._fi.onAckPushToTalk)
        
        # UI request to open an object
        self._fi.connect_signal('open_object', self._broker.onOpenObject)
        #self._broker.connect('return_object', self._fi.returnObject)
        
        # group related methods
        self._fi.connect_signal('new_group', self._gs.onNewGroup)
        self._fi.connect_signal('add_user_to_group',self._gs.onAddUserToGroup)
        self._fi.connect_signal('del_user_from_group', self._gs.onDelUserFromGroup )
        self._fi.connect_signal('show_group', self._gs.onShowGroup )
        self._fi.connect_signal('del_group', self._gs.onDelGroup )
        self._fi.connect_signal('update_group_name', self._gs.onUpdateGroupName ) 

        # response events and new events in group service
        #self._gs.connect('return_groups', self._fi.sendGroups )
        self._gs.connect('group_appeared', self._fi.groupAppeared )
        self._gs.addLookupNameCallback( self._presence.getUserName )

        # Start network thread
        net.start()


    def run(self):
        # Start main application loop
        gobject.threads_init()
        self._mainloop = gobject.MainLoop()
        self._mainloop.run()
            
    @threadtrace
    def onLoginResult(self, obj, result, username):
        """
            Called on interface-connect.
            Sends the UI the list of users and objects around me.
            
            @param dummy: a dummy variable to make signal transmission work.
        """
        import threading
        print "In thread:",threading.currentThread().getName()
        allusers = self._presence.getAllUsers()
        allobjects = self._broker.getAllObjects()
        
            
        #for i in allitems:
            
        """
        allitems = [{'subcommand':uicon.ADD, 'guid':123, 'name':'Kwan', 'status':uicon.AVAILABLE, 'type':uicon.FV},
         {'subcommand':uicon.ADD, 'guid':124, 'name':'An', 'status': uicon.OFFLINE, 'type':uicon.FV},
         {'subcommand':uicon.ADD, 'guid':125, 'name':'John', 'status':uicon.AVAILABLE, 'type':uicon.PHONE},
         {'subcommand':uicon.ADD, 'guid':125, 'name':'Txt->John', 'status':uicon.AVAILABLE, 'type':uicon.TXTMSG, 'priority':uicon.PRIORITY_LOW},
         {'subcommand':uicon.ADD, 'guid':126, 'name':'Voice->Charles', 'status':uicon.AVAILABLE, 'type':uicon.AUDIOMSG, 'priority':uicon.PRIORITY_MEDIUM},
         {'subcommand':uicon.ADD, 'guid':127, 'name':'Poll->John', 'status':uicon.AVAILABLE, 'type':uicon.POLL, 'priority':uicon.PRIORITY_HIGH},
         {'subcommand':uicon.ADD, 'guid':128, 'name':'Partial->John', 'status':uicon.AVAILABLE, 'type':uicon.PARTIAL, 'priority':uicon.PRIORITY_MEDIUM},
         {'subcommand':uicon.ADD, 'guid':129, 'name':'Poll->John', 'status':uicon.AVAILABLE, 'type':uicon.POLLRESULT, 'priority':uicon.PRIORITY_LOW},
         {'subcommand':uicon.ADD, 'guid':130, 'name':'Fungroup', 'status':uicon.AVAILABLE, 'type':uicon.GROUP}]
        
        """
        if result == 1:
            self._fi.loginAck(username, allusers+allobjects)
        else:
            self._fi.loginAck( None, None)
        
    def shutDown(self):
        self._logger.endLog()
        self._db.shutDown()
        print "Ending Log"


def usage():
    print """
    fvengine : fluidvoice v3 application
    
    python fvengine.py [-c <config>] [-f <flash local/remote>]
    
    -h                  print this message
    -a                  run in adhoc network mode
    -i <ifname>         run with the specified interface name (default wlan0)
    
    -c <config>         use asynchronous messaging configuration given in 
                        specified config file
    -f <local/remote>   "local" to use UI on localhost; "remote" to allow usage
                        of remote UI. default is local.
    
    """
    
if __name__ == "__main__":

    o,a = getopt.getopt(sys.argv[1:], 'hc:f:ai:') # : specifies we expect a value after c and f
    opts = {}
    for k,v in o:
        opts[k] = v
    
    # If help has been asked, display usage and exit
    if '-h' in opts:
        usage()
        sys.exit(0)
    
    if '-i' in opts:
        ifname = opts['-i']
    else:
        ifname = "wlan0"
        
    if '-a' in opts:
        common.SetRCVR(ifname)
        
    if '-c' in opts:
        config = opts['-c']
    else:
        print "No config file specified, using default FV config."
        config = "../config/fv"
    
    if '-f' in opts:
        val = opts['-f']
        if val == "remote":
            FLASH_LOCAL = False
        elif val == "local":
            FLASH_LOCAL = True
        else:
            print "Unrecognized value given for -f argument:",val
            usage()
            sys.exit(1)
    # check to see if directories are ready
    checksetup.setupDirs()
    app = Engine(ifname, config)
    try:
        app.run()
    except KeyboardInterrupt:
        app.shutDown()
        am.AsyncManager.instance().shutDown()
        print "Crtl+C pressed. Shutting down."
 
